home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1993…ch: Other People's Memory / ADC Developer CD (1993-03) (''Other People's Memory'')_iso / Dev.CD Mar 93.iso / Technical Documentation / Sample Code / DTS.Lib & Samples / DTS.Draw / TPieObj.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-10-22  |  12.3 KB  |  482 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        TPieObj.c
  5. ** Written by:    Eric Soldan
  6. **
  7. ** Copyright © 1992 Apple Computer, Inc.
  8. ** All rights reserved.
  9. */
  10.  
  11. /* See the files "=How to write your app" and "=Using TreeObj.c" for information
  12. ** on this function. */
  13.  
  14. /* This file implements the messages for the pie object.  Many of the messages
  15. ** can be handled by the rect object, as they deal with a rect structure.  Only
  16. ** a few of them are pie-specific. */
  17.  
  18. /* We have a custom hit-test handler here because there are additional sizing
  19. ** grabbers for the pie object.  The other objects just have grabbers at the
  20. ** corners.  A pie object also has grabber objects to adjust the "pie-slice". */
  21.  
  22.  
  23.  
  24. /*****************************************************************************/
  25.  
  26.  
  27.  
  28. #include "App.h"            /* Get the application includes/typedefs, etc.    */
  29. #include "App.Common.h"        /* Get the stuff in common with rez.            */
  30. #include "App.protos.h"        /* Get the prototypes for the application.        */
  31.  
  32. #ifndef __OSEVENTS__
  33. #include <OSEvents.h>
  34. #endif
  35.  
  36. #ifndef __OSUTILS__
  37. #include <OSUtils.h>
  38. #endif
  39.  
  40. #ifndef __QUICKDRAW__
  41. #include <Quickdraw.h>
  42. #endif
  43.  
  44. #ifndef __STRING__
  45. #include <String.h>
  46. #endif
  47.  
  48. #ifndef __TREEOBJ2__
  49. #include "TreeObj2.h"
  50. #endif
  51.  
  52. #ifndef __UTILITIES__
  53. #include "Utilities.h"
  54. #endif
  55.  
  56.  
  57.  
  58. static OSErr    PieLayerProc(LayerObj theLayer, short message);
  59.  
  60.  
  61.  
  62. /*****************************************************************************/
  63.  
  64.  
  65.  
  66. #pragma segment DrawObjects
  67. long    TPieObj(TreeObjHndl hndl, short message, long data)
  68. {
  69.     ClickInfo    *click;
  70.     Rect        rct;
  71.     TreeObjHndl    hhndl;
  72.     RgnHandle    rgn;
  73.     short        arcs, arcl, arcs2, arcl2, diff, i, angle;
  74.     Point        pt, where, curMouse;
  75.     long        flip, newSize;
  76.     LayerObj    pieLayer;
  77.     EventRecord    option;
  78. #if VH_VERSION
  79.     char        *cptr;
  80. #endif
  81.  
  82.     switch (message) {
  83.         case INITMESSAGE:
  84.             mDerefPie(hndl)->arcStart  = 0;
  85.             mDerefPie(hndl)->arcLength = 360;
  86.             break;
  87.  
  88.         case FREEMESSAGE:
  89.         case COPYMESSAGE:
  90.         case UNDOMESSAGE:
  91.         case CONVERTMESSAGE:
  92.         case FREADMESSAGE:
  93.         case FWRITEMESSAGE:
  94.         case HREADMESSAGE:
  95.         case HWRITEMESSAGE:
  96.         case GETBBOXMESSAGE:
  97.         case SECTBBOXMESSAGE:
  98.         case TARGETMESSAGE:
  99.         case KEYMESSAGE:
  100.         case SETSELECTMESSAGE:
  101.         case GETSELECTMESSAGE:
  102.             return(TRectObj(hndl, message, data));
  103.             break;
  104.  
  105.         case HITTESTMESSAGE:
  106.             click = (ClickInfo *)data;
  107.             hhndl = (TreeObjHndl)TRectObj(hndl, message, data);
  108.                 /* We must call TRectObj::HITTESTMESSAGE to set some static
  109.                 ** variables that TRectObj::SELECTOBJMESSAGE uses. */
  110.             if ((!hhndl) && (click->message == HITTESTGRABBER)) {
  111.                 if (mDerefRoot(GetRootHndl(hndl))->numSelected == 1) {
  112.                     if (mDerefPie(hndl)->selected) {
  113.                         rct     = mDerefPie(hndl)->arc;
  114.                         where   = click->localEvent.where;
  115.                         InsetRect(&rct, -4, -4);
  116.                         if (PtInRect(where, &rct)) {
  117.                             GetMouse(&curMouse);
  118.                             for (i = 0; i < 2; ++i) {
  119.                                 pt = (i) ? mDerefPie(hndl)->arcEnd : mDerefPie(hndl)->arcBegin;
  120.                                 rct.bottom = (rct.top  = pt.v - 3) + 6;
  121.                                 rct.right  = (rct.left = pt.h - 3) + 6;
  122.                                 if (PtInRect(where, &rct)) {
  123.                                     click->localEvent.where = pt;
  124.                                     click->offset.h         = pt.h - curMouse.h;
  125.                                     click->offset.v         = pt.v - curMouse.v;
  126.                                     click->oldFlip          = 0;
  127.                                     click->newFlip          = 0;
  128.                                     click->grabber          = 5 + i;
  129.                                     hhndl = hndl;
  130.                                     break;
  131.                                 }
  132.                             }
  133.                         }
  134.                     }
  135.                 }
  136.             }
  137.             return((long)hhndl);
  138.             break;
  139.  
  140.         case GETRGNMESSAGE:
  141.             rgn = NewRgn();
  142.             NewLayer(&pieLayer, nil, PieLayerProc, nil, 0, (long)hndl);
  143.             if (pieLayer) {
  144.                 SetLayerWorld(pieLayer);
  145.                 TPieObj(hndl, DRAWMESSAGE, DRAWMASK);
  146.                 BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  147.                 ResetLayerWorld(pieLayer);
  148.                 DisposeLayer(pieLayer);
  149.             }
  150.             return((long)rgn);
  151.             break;
  152.  
  153.         case SETBBOXMESSAGE:
  154.             TRectObj(hndl, message, data);
  155.             CalcPiePoints(hndl);
  156.             break;
  157.  
  158.         case DRAWMESSAGE:
  159.             rct = mDerefPie(hndl)->arc;
  160.             if (!EmptyRect(&rct)) {
  161.                 arcs = mDerefPie(hndl)->arcStart;
  162.                 arcl = mDerefPie(hndl)->arcLength;
  163.                 switch (data) {
  164.                     case DRAWOBJ:
  165.                         FillArc(&rct, arcs, arcl, &qd.white);
  166.                         FrameArc(&rct, arcs, arcl);
  167.                         pt = mDerefPie(hndl)->arcBegin;
  168.                         MoveTo(pt.h, pt.v);
  169.                         pt = mDerefPie(hndl)->center;
  170.                         LineTo(pt.h, pt.v);
  171.                         pt = mDerefPie(hndl)->arcEnd;
  172.                         LineTo(pt.h, pt.v);
  173.                         break;
  174.                     case ERASEOBJ:
  175.                         EraseArc(&rct, arcs, arcl);
  176.                         break;
  177.                     case DRAWSELECT:
  178.                         if (mDerefPie(hndl)->selected) {
  179.                             TRectObj(hndl, message, data);
  180.                             for (i = 0; i < 2; ++i) {
  181.                                 pt = (i) ? mDerefPie(hndl)->arcEnd : mDerefPie(hndl)->arcBegin;
  182.                                 rct.bottom = (rct.top  = pt.v - 3) + 6;
  183.                                 rct.right  = (rct.left = pt.h - 3) + 6;
  184.                                 InvertRect(&rct);
  185.                                 arcl = mDerefPie(hndl)->arcLength;
  186.                                 if ((arcl == -360) || (!arcl) || (arcl == 360)) break;
  187.                             }
  188.                         }
  189.                         break;
  190.                     case DRAWGHOST:
  191.                         PenMode(patXor);
  192.                         FrameArc(&rct, arcs, arcl);
  193.                         PenNormal();
  194.                         break;
  195.                     case DRAWMASK:
  196.                         FillArc(&rct, arcs, arcl, &qd.black);
  197.                         FrameArc(&rct, arcs, arcl);
  198.                         pt = mDerefPie(hndl)->arcBegin;
  199.                         MoveTo(pt.h, pt.v);
  200.                         pt = mDerefPie(hndl)->center;
  201.                         LineTo(pt.h, pt.v);
  202.                         pt = mDerefPie(hndl)->arcEnd;
  203.                         LineTo(pt.h, pt.v);
  204.                         break;
  205.                 }
  206.             }
  207.             break;
  208.  
  209.         case PRINTMESSAGE:
  210.             TPieObj(hndl, DRAWMESSAGE, DRAWOBJ);
  211.             break;
  212.  
  213. #if VH_VERSION
  214.         case VHMESSAGE:
  215.             cptr = ((VHFormatDataPtr)data)->data;
  216.             ccatchr(cptr, 13, 2);
  217.             ccat   (cptr, "$10: TPieObj:");
  218.             ccatchr(cptr, 13, 1);
  219.             ccat   (cptr, "  $00: selected = ");
  220.             ccatdec(cptr, mDerefPie(hndl)->selected);
  221.             ccatchr(cptr, 13, 1);
  222.             rct = mDerefPie(hndl)->arc;
  223.             ccat   (cptr, "  $02: pie      = (");
  224.             ccatdec(cptr, rct.top);
  225.             ccat   (cptr, ",");
  226.             ccatdec(cptr, rct.left);
  227.             ccat   (cptr, ",");
  228.             ccatdec(cptr, rct.bottom);
  229.             ccat   (cptr, ",");
  230.             ccatdec(cptr, rct.right);
  231.             ccat   (cptr, ")");
  232.             ccatchr(cptr, 13, 1);
  233.             ccat   (cptr, "  $0A: arcStart  = ");
  234.             ccatdec(cptr, mDerefPie(hndl)->arcStart);
  235.             ccatchr(cptr, 13, 1);
  236.             ccat   (cptr, "  $0C: arcLength = ");
  237.             ccatdec(cptr, mDerefPie(hndl)->arcLength);
  238.             ccatchr(cptr, 13, 1);
  239.             ccat   (cptr, "  $0E: center    = (");
  240.             ccatdec(cptr, mDerefPie(hndl)->center.v);
  241.             ccat   (cptr, ",");
  242.             ccatdec(cptr, mDerefPie(hndl)->center.h);
  243.             ccat   (cptr, ")");
  244.             ccatchr(cptr, 13, 1);
  245.             ccat   (cptr, "  $12: arcBegin  = (");
  246.             ccatdec(cptr, mDerefPie(hndl)->arcBegin.v);
  247.             ccat   (cptr, ",");
  248.             ccatdec(cptr, mDerefPie(hndl)->arcBegin.h);
  249.             ccat   (cptr, ")");
  250.             ccatchr(cptr, 13, 1);
  251.             ccat   (cptr, "  $16: arcEnd    = (");
  252.             ccatdec(cptr, mDerefPie(hndl)->arcEnd.v);
  253.             ccat   (cptr, ",");
  254.             ccatdec(cptr, mDerefPie(hndl)->arcEnd.h);
  255.             ccat   (cptr, ")");
  256.             ccatchr(cptr, 13, 1);
  257.             return(true);
  258.             break;
  259. #endif
  260.  
  261.         case CLICKMESSAGE:
  262.             TRectObj(hndl, message, data);
  263.             click = (ClickInfo *)data;
  264.             if (click->message == CLICKDRAG) {
  265.                 AddPt(click->offset, &mDerefPie(hndl)->center);
  266.                 AddPt(click->offset, &mDerefPie(hndl)->arcBegin);
  267.                 AddPt(click->offset, &mDerefPie(hndl)->arcEnd);
  268.             }
  269.             break;
  270.  
  271.         case SIZEMESSAGE:
  272.             click = (ClickInfo *)data;
  273.             if (click->grabber <= 4) {
  274.                 newSize = TRectObj(hndl, message, data);
  275.                 click = (ClickInfo *)data;
  276.                 if (flip = (click->oldFlip ^ click->newFlip)) {
  277.                     arcs = mDerefPie(hndl)->arcStart;
  278.                     arcl = mDerefPie(hndl)->arcLength;
  279.                     if (flip & VFLIPOBJ) {
  280.                         arcs -= (i = (arcs < 180) ? 0 : 180);
  281.                         arcs = 180 - arcs;
  282.                         arcl = -arcl;
  283.                         arcs += i;
  284.                     }
  285.                     if (flip & HFLIPOBJ) {
  286.                         arcs = 360 - arcs;
  287.                         arcl = -arcl;
  288.                     }
  289.                     mDerefPie(hndl)->arcStart  = arcs;
  290.                     mDerefPie(hndl)->arcLength = arcl;
  291.                 }
  292.                 CalcPiePoints(hndl);
  293.                 return(newSize);
  294.             }
  295.  
  296.             GetMouse(&curMouse);
  297.             curMouse.h += click->offset.h;
  298.             curMouse.v += click->offset.v;
  299.             rct = mDerefPie(hndl)->arc;
  300.  
  301.             arcs = arcs2 = mDerefPie(hndl)->arcStart;
  302.             arcl = arcl2 = mDerefPie(hndl)->arcLength;
  303.  
  304.             PtToAngle(&rct, curMouse, &angle);
  305.  
  306.             if (click->grabber == 6) {        /* Handle 2nd grabber as reverse first grabber case. */
  307.                 click->grabber = 5;
  308.                 arcs += arcl;
  309.                 arcl  = -arcl;
  310.                 while (arcs >  360) arcs -= 360;
  311.                 while (arcs <    0) arcs += 360;
  312.             }
  313.  
  314.             diff = angle - arcs;
  315.             arcs = angle;
  316.             OSEventAvail(nullEvent, &option);
  317.             if (!(option.modifiers & shiftKey)) {
  318.                 while (diff >  180) diff -= 360;        /* Force 1 change to be less than 180. */
  319.                 while (diff < -180) diff += 360;
  320.                 arcl   -= diff;
  321.                 while (arcl >  360) arcl -= 360;
  322.                 while (arcl < -360) arcl += 360;
  323.             }
  324.  
  325.             if ((arcs != arcs2) || (arcl != arcl2)) {
  326.                 mDerefPie(hndl)->arcStart  = arcs;
  327.                 mDerefPie(hndl)->arcLength = arcl;
  328.                 CalcPiePoints(hndl);
  329.                 return(true);
  330.             }
  331.             break;
  332.  
  333.         default:
  334.             break;
  335.     }
  336.  
  337.     return(noErr);
  338. }
  339.  
  340.  
  341.  
  342. /*****************************************************************************/
  343.  
  344.  
  345.  
  346. #pragma segment DrawObjects
  347. OSErr    CalcPiePoints(TreeObjHndl hndl)
  348. {
  349.     OSErr        err;
  350.     Rect        rct;
  351.     short        arcs, arcl, i, angle;
  352.     RgnHandle    rgn;
  353.     Point        pt;
  354.     long        ll;
  355.     LayerObj    pieLayer;
  356.  
  357.     if (err = NewLayer(&pieLayer, nil, PieLayerProc, nil, 0, (long)hndl)) return(err);
  358.  
  359.     rct  = mDerefPie(hndl)->arc;
  360.     arcs = mDerefPie(hndl)->arcStart;
  361.     arcl = mDerefPie(hndl)->arcLength;
  362.  
  363.     SetLayerWorld(pieLayer);
  364.     rgn = NewRgn();
  365.  
  366.     EraseRect(&rct);
  367.     FillArc(&rct, 90, 90, &qd.black);
  368.  
  369.     BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  370.     pt = *(Point *)(&(*rgn)->rgnBBox);
  371.     ll = PinRect(&rct, pt);
  372.     pt = *(Point *)≪
  373.     mDerefPie(hndl)->center = pt;
  374.  
  375.     for (i = 0; i < 2; ++i) {
  376.         angle = (i) ? (arcs + arcl) : (arcs);
  377.         while (angle < 0)    angle += 360;
  378.         while (angle >= 360) angle -= 360;
  379.         EraseRect(&rct);
  380.         if (angle < 90) {
  381.             FillArc(&rct, angle, 90, &qd.black);
  382.             BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  383.             pt.v = (*rgn)->rgnBBox.top;
  384.             EraseRect(&rct);
  385.             FillArc(&rct, angle, -90, &qd.black);
  386.             BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  387.             pt.h = (*rgn)->rgnBBox.right;
  388.             if (angle > 45)
  389.                 --pt.h;
  390.         }
  391.         if ((angle >= 90) && (angle < 180)) {
  392.             FillArc(&rct, angle, 90, &qd.black);
  393.             BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  394.             pt.h = (*rgn)->rgnBBox.right;
  395.             EraseRect(&rct);
  396.             FillArc(&rct, angle, -90, &qd.black);
  397.             BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  398.             pt.v = (*rgn)->rgnBBox.bottom;
  399.             if (angle < 135)
  400.                 --pt.h;
  401.             else
  402.                 --pt.v;
  403.         }
  404.         if ((angle >= 180) && (angle < 270)) {
  405.             FillArc(&rct, angle, 90, &qd.black);
  406.             BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  407.             pt.v = (*rgn)->rgnBBox.bottom;
  408.             EraseRect(&rct);
  409.             FillArc(&rct, angle, -90, &qd.black);
  410.             BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  411.             pt.h = (*rgn)->rgnBBox.left;
  412.             if (angle < 225)
  413.                 --pt.v;
  414.         }
  415.         if (angle >= 270) {
  416.             FillArc(&rct, angle, 90, &qd.black);
  417.             BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  418.             pt.h = (*rgn)->rgnBBox.left;
  419.             EraseRect(&rct);
  420.             FillArc(&rct, angle, -90, &qd.black);
  421.             BitMapToRegion(rgn, (BitMapPtr)(*((CGrafPtr)(*pieLayer)->layerPort)->portPixMap));
  422.             pt.v = (*rgn)->rgnBBox.top;
  423.         }
  424.         ll = PinRect(&rct, pt);
  425.         pt = *(Point *)≪
  426.         (i) ? (mDerefPie(hndl)->arcEnd = pt) : (mDerefPie(hndl)->arcBegin = pt);
  427.     }
  428.  
  429.     DisposeRgn(rgn);
  430.     ResetLayerWorld(pieLayer);
  431.     DisposeLayer(pieLayer);
  432.     return(noErr);
  433. }
  434.  
  435.  
  436.  
  437. /*****************************************************************************/
  438.  
  439.  
  440.  
  441. static OSErr    PieLayerProc(LayerObj theLayer, short message)
  442. {
  443.     OSErr        err;
  444.     TreeObjHndl    pie;
  445.     Rect        rct;
  446.     CGrafPtr    keepPort;
  447.     GDHandle    keepGDevice;
  448.     GWorldPtr    layerWorld;
  449.  
  450.     switch (message) {
  451.         case kLayerInit:
  452.             err = noErr;
  453.             if (theLayer) {
  454.                 if (!(*theLayer)->layerPort) {
  455.                     pie = (TreeObjHndl)(*theLayer)->layerData;
  456.                     rct = mDerefPie(pie)->arc;
  457.                     GetGWorld(&keepPort, &keepGDevice);        /* Keep the GWorld. */
  458.                     err = NewGWorld(&layerWorld, 1, &rct, nil, nil, 0);
  459.                     if (err == noErr) {
  460.                         (*theLayer)->layerOwnsPort = true;
  461.                         SetPort((*theLayer)->layerPort = (GrafPtr)layerWorld);
  462.                         SetOrigin(rct.left, rct.top);
  463.                         EraseRect(&rct);
  464.                     }
  465.                     SetGWorld(keepPort, keepGDevice);        /* Restore the kept GWorld. */
  466.                 }
  467.             }
  468.             else err = paramErr;
  469.             break;
  470.  
  471.         default:
  472.             err = DefaultLayerProc(theLayer, message);
  473.                 /* Default behavior for everything else. */
  474.             break;
  475.     }
  476.  
  477.     return(err);
  478. }
  479.  
  480.  
  481.  
  482.